home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / amiga / asrc29k.lha / iface.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-08  |  9.1 KB  |  440 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "iface.h"
  4. #include "ip.h"
  5. #include "netuser.h"
  6. #include "cmdparse.h"
  7. #include "commands.h"
  8. #include "enet.h"
  9. #include "ax25.h"
  10. #include "proc.h"
  11.  
  12. static void showiface __ARGS((struct iface *ifp));
  13. static int mask2width __ARGS((int32 mask));
  14. static int ifipaddr __ARGS((int argc,char *argv[],void *p));
  15. static int iflinkadr __ARGS((int argc,char *argv[],void *p));
  16. static int ifbroad __ARGS((int argc,char *argv[],void *p));
  17. static int ifnetmsk __ARGS((int argc,char *argv[],void *p));
  18. static int ifrxbuf __ARGS((int argc,char *argv[],void *p));
  19. static int ifmtu __ARGS((int argc,char *argv[],void *p));
  20. static int ifforw __ARGS((int argc,char *argv[],void *p));
  21. static int ifencap __ARGS((int argc,char *argv[],void *p));
  22. static int ifdescr __ARGS((int argc,char *argv[],void *p));
  23.  
  24. /* Interface list header */
  25. struct iface *Ifaces = &Loopback;
  26.  
  27. /* Loopback pseudo-interface */
  28. struct iface Loopback = {
  29.     NULLIF,
  30.     "loopback",
  31.     NULLCHAR,    /* description */
  32.     TYPE_NONE,
  33.     &Iftypes[0],
  34.     0x7f000001,    /* 127.0.0.1 */
  35.     0xffffffff,    /* 255.255.255.255 */
  36.     0xffffffff,
  37.     NULL,
  38.     NULL,
  39.     NULL,
  40.     NULL,
  41.     NULL,
  42.     MAXINT16,    /* No limit on MTU */
  43.     0,
  44.     0,
  45.     0,
  46.     0,
  47.     0,
  48.     NULLCHAR,
  49.     NULLFILE,
  50.     NULLCHAR,
  51.     NULLIF,
  52.     0,
  53.     0,
  54.     0,
  55.     0,
  56.     0,
  57.     0,
  58.     NULLPROC,
  59.     NULLPROC
  60. };
  61.  
  62. char Noipaddr[] = "IP address field missing, and ip address not set\n";
  63.  
  64. struct cmds Ifcmds[] = {
  65.     "broadcast",        ifbroad,    0, 2, NULLCHAR,
  66.     "description",        ifdescr,    0, 0, NULLCHAR,
  67.     "encapsulation",    ifencap,    0, 2, NULLCHAR,
  68.     "forward",        ifforw,        0, 2, NULLCHAR,
  69.     "ipaddress",        ifipaddr,    0, 2, NULLCHAR,
  70.     "linkaddress",        iflinkadr,    0, 2, NULLCHAR,
  71.     "mtu",            ifmtu,        0, 2, NULLCHAR,
  72.     "netmask",        ifnetmsk,    0, 2, NULLCHAR,
  73.     "rxbuf",        ifrxbuf,    0, 2, NULLCHAR,
  74.     NULLCHAR,
  75. };
  76.  
  77. /* Set interface parameters */
  78. int doifconfig(argc,argv,p)
  79. int argc;
  80. char *argv[];
  81. void *p;
  82. {
  83.     struct iface *ifp;
  84.     int i;
  85.  
  86.     if(argc < 2){
  87.         for(ifp = Ifaces;ifp != NULLIF;ifp = ifp->next)
  88.             showiface(ifp);
  89.         return 0;
  90.     }
  91.     if((ifp = if_lookup(argv[1])) == NULLIF){
  92.         tprintf(Badinterface,argv[1]);
  93.         return 1;
  94.     }
  95.     if(argc == 2){
  96.         showiface(ifp);
  97.         return 0;
  98.     }
  99.     if(argc == 3)
  100.         return subcmd(Ifcmds,argc,argv,p);
  101.     for(i=2;i<argc-1;i+=2)
  102.         subcmd(Ifcmds,3,&argv[i-1],ifp);
  103.  
  104.     return 0;
  105. }
  106.  
  107. /*give a little description for each interface - WG7J*/
  108. static int
  109. ifdescr(argc,argv,p)
  110. int argc;
  111. char *argv[];
  112. void *p;
  113. {
  114.     struct iface *ifp = p;
  115.  
  116. #ifdef NETROM
  117. #ifdef ENCAP
  118.     if((ifp == &Loopback) || (ifp == &Encap) || (ifp == Nr_iface))
  119. #else
  120.     if((ifp == &Loopback) || (ifp == Nr_iface))
  121. #endif /*ENCAP*/
  122. #else  /*NETROM*/
  123. #ifdef ENCAP
  124.     if((ifp == &Loopback) || (ifp == &Encap))
  125. #else
  126.     if(ifp == &Loopback)
  127. #endif /*ENCAP*/
  128. #endif /*NETROM*/
  129.         return 0;
  130.  
  131.     if(ifp->descr != NULLCHAR){
  132.         free(ifp->descr);
  133.         ifp->descr = NULLCHAR;        /* reset the pointer */
  134.     }
  135.     if(!strlen(argv[1]))
  136.         return 0;           /* clearing the buffer */
  137.  
  138.     ifp->descr = mallocw(strlen(argv[1])+5); /* allow for the EOL char etc */
  139.     strcpy(ifp->descr, argv[1]);
  140.     strcat(ifp->descr, "\n");         /* add the EOL char */
  141.  
  142.     return 0;
  143. }
  144.  
  145. /* Set interface IP address */
  146. static int ifipaddr(argc,argv,p)
  147. int argc;
  148. char *argv[];
  149. void *p;
  150. {
  151.     struct iface *ifp = p;
  152.  
  153.     ifp->addr = resolve(argv[1]);
  154.     return 0;
  155. }
  156.  
  157.  
  158. /* Set link (hardware) address */
  159. static int iflinkadr(argc,argv,p)
  160. int argc;
  161. char *argv[];
  162. void *p;
  163. {
  164.     struct iface *ifp = p;
  165.  
  166.     if(ifp->iftype == NULLIFT || ifp->iftype->scan == NULL){
  167.         tprintf("Can't set link address\n");
  168.         return 1;
  169.     }
  170.     if(ifp->hwaddr != NULLCHAR)
  171.         free(ifp->hwaddr);
  172.     ifp->hwaddr = mallocw(ifp->iftype->hwalen);
  173.     (*ifp->iftype->scan)(ifp->hwaddr,argv[1]);
  174.     return 0;
  175. }
  176.  
  177. /* Set interface broadcast address. This is actually done
  178.  * by installing a private entry in the routing table.
  179.  */
  180. static int ifbroad(argc,argv,p)
  181. int argc;
  182. char *argv[];
  183. void *p;
  184. {
  185.     struct iface *ifp = p;
  186.     struct route *rp;
  187.  
  188.     rp = rt_blookup(ifp->broadcast,32);
  189.     if(rp != NULLROUTE && rp->iface == ifp)
  190.         rt_drop(ifp->broadcast,32);
  191.     ifp->broadcast = resolve(argv[1]);
  192.     rt_add(ifp->broadcast,32,0L,ifp,1L,0L,1);
  193.     return 0;
  194. }
  195.  
  196. /* Set the network mask. This is actually done by installing
  197.  * a routing entry.
  198.  */
  199. static int ifnetmsk(argc,argv,p)
  200. int argc;
  201. char *argv[];
  202. void *p;
  203. {
  204.     struct iface *ifp = p;
  205.     struct route *rp;
  206.  
  207.     /* Remove old entry if it exists */
  208.     rp = rt_blookup(ifp->addr & ifp->netmask,mask2width(ifp->netmask));
  209.     if(rp != NULLROUTE)
  210.         rt_drop(rp->target,rp->bits);
  211.  
  212.     ifp->netmask = htol(argv[1]);
  213.     rt_add(ifp->addr,mask2width(ifp->netmask),0L,ifp,0L,0L,0);
  214.     return 0;
  215. }
  216.  
  217. /* Command to set interface encapsulation mode */
  218. static int ifencap(argc,argv,p)
  219. int argc;
  220. char *argv[];
  221. void *p;
  222. {
  223.     struct iface *ifp = p;
  224.  
  225.     if(setencap(ifp,argv[1]) != 0){
  226.         tprintf("Encapsulation mode '%s' unknown\n",argv[1]);
  227.         return 1;
  228.     }
  229.     return 0;
  230. }
  231.  
  232. /* Function to set encapsulation mode */
  233. int setencap(ifp,mode)
  234. struct iface *ifp;
  235. char *mode;
  236. {
  237.     struct iftype *ift;
  238.  
  239.     for(ift = &Iftypes[0];ift->name != NULLCHAR;ift++)
  240.         if(strnicmp(ift->name,mode,strlen(mode)) == 0)
  241.             break;
  242.     if(ift->name == NULLCHAR){
  243.         return -1;
  244.     }
  245.     ifp->iftype = ift;
  246.     ifp->send = ift->send;
  247.     ifp->output = ift->output;
  248.     ifp->type = ift->type;
  249.     return 0;
  250. }
  251.  
  252. /* Set interface receive buffer size */
  253. static int ifrxbuf(argc,argv,p)
  254. int argc;
  255. char *argv[];
  256. void *p;
  257. {
  258.     return 0;    /* To be written */
  259. }
  260.  
  261. /* Set interface Maximum Transmission Unit */
  262. static int ifmtu(argc,argv,p)
  263. int argc;
  264. char *argv[];
  265. void *p;
  266. {
  267.     struct iface *ifp = p;
  268.  
  269.     ifp->mtu = atoi(argv[1]);
  270.     return 0;
  271. }
  272.  
  273. /* Set interface forwarding */
  274. static int ifforw(argc,argv,p)
  275. int argc;
  276. char *argv[];
  277. void *p;
  278. {
  279.     struct iface *ifp = p;
  280.  
  281.     ifp->forw = if_lookup(argv[1]);
  282.     if(ifp->forw == ifp)
  283.         ifp->forw = NULLIF;
  284.     return 0;
  285. }
  286.  
  287. /* Display the parameters for a specified interface */
  288. static void showiface(ifp)
  289. register struct iface *ifp;
  290. {
  291.     char tmp[25];
  292.  
  293.     tprintf("%-10s IP addr %s MTU %u Link encap ",ifp->name,
  294.      inet_ntoa(ifp->addr),(int)ifp->mtu);
  295.     if(ifp->iftype == NULLIFT){
  296.         tprintf("not set\n");
  297.     } else {
  298.          tprintf("%s\n",ifp->iftype->name);
  299.         if(ifp->iftype->format != NULL && ifp->hwaddr != NULLCHAR)
  300.             tprintf("           Link addr %s\n",
  301.              (*ifp->iftype->format)(tmp,ifp->hwaddr));
  302.     }
  303.     tprintf("           flags %u trace 0x%x netmask 0x%08lx broadcast %s\n",
  304.         ifp->flags,ifp->trace,ifp->netmask,inet_ntoa(ifp->broadcast));
  305.     if(ifp->forw != NULLIF)
  306.         tprintf("           output forward to %s\n",ifp->forw->name);
  307.     tprintf("           sent: ip %lu tot %lu recv: ip %lu tot %lu\n",
  308.      ifp->ipsndcnt,ifp->rawsndcnt,ifp->iprecvcnt,ifp->rawrecvcnt);
  309.     if(ifp->descr != NULLCHAR)
  310.          tprintf("           descr: %s",ifp->descr);
  311. }
  312.  
  313. /* Command to detach an interface */
  314. int
  315. dodetach(argc,argv,p)
  316. int argc;
  317. char *argv[];
  318. void *p;
  319. {
  320.     register struct iface *ifp;
  321.  
  322.     if((ifp = if_lookup(argv[1])) == NULLIF){
  323.         tprintf(Badinterface,argv[1]);
  324.         return 1;
  325.     }
  326.     if(if_detach(ifp) == -1)
  327.         tprintf("Can't detach loopback interface\n");
  328.     return 0;
  329. }
  330. /* Detach a specified interface */
  331. int
  332. if_detach(ifp)
  333. register struct iface *ifp;
  334. {
  335.     struct iface *iftmp;
  336.     struct route *rp,*rptmp;
  337.     int i,j;
  338.  
  339.     if(ifp == &Loopback)
  340.         return -1;
  341.  
  342.     /* Drop all routes that point to this interface */
  343.     if(R_default.iface == ifp)
  344.         rt_drop(0L,0);    /* Drop default route */
  345.  
  346.     for(i=0;i<NROUTE;i++){
  347.         for(j=0;j<32;j++){
  348.             for(rp = Routes[j][i];rp != NULLROUTE;rp = rptmp){
  349.                 /* Save next pointer in case we delete this entry */
  350.                 rptmp = rp->next;
  351.                 if(rp->iface == ifp)
  352.                     rt_drop(rp->target,rp->bits);
  353.             }
  354.         }
  355.     }
  356.     /* Unforward any other interfaces forwarding to this one */
  357.     for(iftmp = Ifaces;iftmp != NULLIF;iftmp = iftmp->next){
  358.         if(iftmp->forw == ifp)
  359.             iftmp->forw = NULLIF;
  360.     }
  361.     killproc(ifp->proc);
  362.     killproc(ifp->proc1);
  363.     /* Call device shutdown routine, if any */
  364.     if(ifp->stop != NULLFP)
  365.         (*ifp->stop)(ifp);
  366.  
  367.     /* Free allocated memory associated with this interface */
  368.     if(ifp->name != NULLCHAR)
  369.         free(ifp->name);
  370.     if(ifp->hwaddr != NULLCHAR)
  371.         free(ifp->hwaddr);
  372.  
  373.     /* Remove from interface list */
  374.     if(ifp == Ifaces){
  375.         Ifaces = ifp->next;
  376.     } else {
  377.         /* Search for entry just before this one
  378.          * (necessary because list is only singly-linked.)
  379.          */
  380.         for(iftmp = Ifaces;iftmp != NULLIF ;iftmp = iftmp->next)
  381.             if(iftmp->next == ifp)
  382.                 break;
  383.         if(iftmp != NULLIF && iftmp->next == ifp)
  384.             iftmp->next = ifp->next;
  385.     }
  386.     /* Finally free the structure itself */
  387.     free((char *)ifp);
  388.     return 0;
  389. }
  390.  
  391. /* Given the ascii name of an interface, return a pointer to the structure,
  392.  * or NULLIF if it doesn't exist
  393.  */
  394. struct iface *
  395. if_lookup(name)
  396. char *name;
  397. {
  398.     register struct iface *ifp;
  399.  
  400.     for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  401.         if(strcmp(ifp->name,name) == 0)
  402.             break;
  403.     return ifp;
  404. }
  405.  
  406. /* Return iface pointer if 'addr' belongs to one of our interfaces,
  407.  * NULLIF otherwise.
  408.  * This is used to tell if an incoming IP datagram is for us, or if it
  409.  * has to be routed.
  410.  */
  411. struct iface *
  412. ismyaddr(addr)
  413. int32 addr;
  414. {
  415.     register struct iface *ifp;
  416.  
  417.     for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  418.         if(addr == ifp->addr)
  419.             break;
  420.     return ifp;
  421. }
  422.  
  423. /* Given a network mask, return the number of contiguous 1-bits starting
  424.  * from the most significant bit.
  425.  */
  426. static int
  427. mask2width(mask)
  428. int32 mask;
  429. {
  430.     int width,i;
  431.  
  432.     width = 0;
  433.     for(i = 31;i >= 0;i--){
  434.         if(!(mask & (1L << i)))
  435.             break;
  436.         width++;
  437.     }
  438.     return width;
  439. }
  440.